//
//  LQRefreshControl.swift
//  CustomWeiBo
//
//  Created by laiqiang on 21/6/14.
//  Copyright © 2021年 laiqiang. All rights reserved.
//

import UIKit

//刷新状态变化的临界点
fileprivate let LQContentOffset:CGFloat = 60

enum LQRefreshStatus {
    case Normal
    case Pull
    case WillRefresh//超过零界点，放撒了
}

//刷新相关的逻辑处理
class LQRefreshControl: UIControl {
    
    //刷新控件的父视图，适用于 uitabview，uiscrolview，colloctionview
    fileprivate weak var scrollview:UIScrollView?
    
    //刷新视图
    fileprivate lazy var refreshView:LQRefreshView = LQRefreshView.refrshView()
    
    //构造函数
    init() {
        super.init(frame: CGRect())
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        setupUI()
    }
    
    //添加到父视图时－会调用
    //添加到父视图时，new super view ＝ 父视图
    //父视图被释放时－会调用
    //当父视图被移除，new super view ＝ nil
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        print("\(newSuperview)")
        
        //判断父视图的类型
        guard let sv = newSuperview as? UIScrollView else {
            return
        }
        scrollview = sv
        
        //kvo，监听父视图contentOffset
        scrollview?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        
    }
    
    //当前视图，从父视图移除
    override func removeFromSuperview() {
        
        scrollview?.removeObserver(self, forKeyPath: "contentOffset")
        
        super.removeFromSuperview()//这里已经scrollview ＝ nil了只能在之前使用
        
        
    }
    
    //kvo监听统一回调
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("\(scrollview?.contentOffset)")
        
        guard let sv = scrollview else {
            return
        }
        
        //初始高度 应该是0，
        let height = -(sv.contentInset.top + sv.contentOffset.y)
        
        if height < 0 {//向上走
            return
        }
        
        
        //根据高度 设置刷新控件的frame
        self.frame = CGRect(x: 0,
                            y: -height,
                            width: sv.bounds.width,
                            height: height)
        
        //零界点
        if sv.isDragging {//是否拖拽
            
            if height > LQContentOffset && refreshView.refreshStatus == .Normal {//超过线，正常状态 ＝ 正在下拉（瞬间进入，修改状态，在下拉不进了）
                
                print(".Normal == 放手就刷新。。。。")
                refreshView.setupRefreshStatus(status: .Pull)
            }
            else if height <= LQContentOffset && refreshView.refreshStatus == .Pull{//没过线，下拉状态 ＝ 正在向上回收（瞬间进入，修改状态，在下拉不进了）
                refreshView.setupRefreshStatus(status: .Normal)
                print(".Normal == 需要使劲拉。。。")
            }
        }
        else{
            //放手－－状态不回变化了，刷新后改成。normal，才回进入上面的方法
            if refreshView.refreshStatus == .Pull {//下拉超过零界点，只进入一次。
                //开始刷新
                beginRefreshing()
                
                //发送刷新事件
                sendActions(for: .valueChanged)
            }
        }
    }
    
    
    func beginRefreshing() {
        
        //判断父视图
        guard let sv = scrollview else {
            
            return
        }
        
        if refreshView.refreshStatus == .WillRefresh {
            
            return
        }
        
        //设置刷新状态
        refreshView.setupRefreshStatus(status: .WillRefresh)
        
        //调整insert间距
        var inset = sv.contentInset
        inset.top += LQContentOffset
        sv.contentInset = inset
    }
    
    func endRefreshing() {
        
        //判断父视图
        guard let sv = scrollview else {
            
            return
        }
        
        if refreshView.refreshStatus != .WillRefresh {
            
            return
        }
        
        //恢复状态
        refreshView.setupRefreshStatus(status: .Normal)
        
        //恢复表格insert
        var inset = sv.contentInset
        inset.top -= LQContentOffset
        sv.contentInset = inset
    }

}

extension LQRefreshControl {

    fileprivate func setupUI() {
        
        backgroundColor = UIColor.white
        
//        clipsToBounds = true
        
        //添加刷新视图 -- 加载完成 xib默认的宽高
        addSubview(refreshView)
        
        //自动布局－设置自动布局就没有了宽高，需要指定
        refreshView.translatesAutoresizingMaskIntoConstraints = false//禁止自适应
        
        //和self 左右居中对齐
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .centerX,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .centerX,
                                         multiplier: 1,
                                         constant: 0))
        //和self 垂直底部对齐
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .bottom,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .bottom,
                                         multiplier: 1,
                                         constant: 0))
        //宽度
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .width,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1,
                                         constant: refreshView.bounds.width))
        //高度
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .height,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1,
                                         constant: refreshView.bounds.height))
        
    }
    
}
